package com.urbanski.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.Closeable;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/**
 * Contains utility methods for file operations
 * @author murbanski004
 *
 */
public class IOUtils
{
	private static final int DEFAULT_BUFFER_SIZE = 1024;

	/**
	 * Reads the specified file and returns its contents as a String
	 * @param file
	 * @return
	 * @throws IOException
	 */
	public static String fileToString(File file) throws IOException
	{
		return fileToString(file, DEFAULT_BUFFER_SIZE);
	}

	/**
	 * Reads the specified file and returns its contents as a String
	 * @param filename
	 * @return
	 * @throws IOException
	 */
	public static String fileToString(String filename) throws IOException
	{
		return fileToString(new File(filename), DEFAULT_BUFFER_SIZE);
	}

	/**
	 * Reads the specified file and returns its contents as a String, reading the file user a buffer
	 * of the specified size
	 * @param file
	 * @return
	 * @throws IOException
	 * @throws IllegalArgumentException if bufferSize is not positive
	 */
	public static String fileToString(File file, int bufferSize) throws IOException
	{
		if (bufferSize <= 0)
		{
			throw new IllegalArgumentException("Buffer size (" + bufferSize + ") must be positive");
		}
		
		BufferedReader reader = null;
		StringBuilder sb = new StringBuilder();

		try
		{
			reader = new BufferedReader(new FileReader(file));
			char[] buffer = new char[bufferSize];
			int read;

			while ((read = reader.read(buffer)) == bufferSize)
			{
				sb.append(buffer);
			}

			if (read > 0)
			{
				sb.append(buffer, 0, read);
			}

			return sb.toString();
		}
		finally
		{
			if (reader != null)
			{
				try
				{
					reader.close();
				}
				catch (IOException e)
				{
				}
			}
		}
	}

	/**
	 * Reads the specified file and returns its contents as a String, reading the file user a buffer
	 * of the specified size
	 * @param file
	 * @return
	 * @throws IOException
	 * @throws IllegalArgumentException if bufferSize is not positive
	 */
	public static String fileToString(String filename, int bufferSize) throws IOException
	{
		return fileToString(new File(filename), bufferSize);
	}
	
	public static void stringToFile(String string, String filename) throws IOException
	{
		stringToFile(string, filename, DEFAULT_BUFFER_SIZE);
	}
	
	public static void stringToFile(String string, File file) throws IOException
	{
		stringToFile(string, file, DEFAULT_BUFFER_SIZE);
	}
	
	public static void stringToFile(String string, String filename, int bufferSize) throws IOException
	{
		stringToFile(string, new File(filename), bufferSize);
	}
	
	public static void stringToFile(String string, File file, int bufferSize) throws IOException
	{
		BufferedWriter writer = new BufferedWriter(new FileWriter(file), bufferSize);
		
		writer.write(string);
		
		writer.close();
	}
	
	/**
	 * Closes the specified reader and silently ignores any IOException that occurs
	 * @param closeable
	 */
	public static void close(Closeable closeable)
	{
		try
		{
			closeable.close();
		}
		catch (IOException e)
		{
			
		}
	}
	
	public static boolean isReadable(File file)
	{
		return file.canRead();
	}
	
	public static boolean isWriteable(File file)
	{
		return file.canWrite();
	}
	
	public static boolean isExecutable(File file)
	{
		return file.canExecute();
	}
	
	public static boolean isReadableDirectory(File file)
	{
		return file.canRead() && file.isDirectory();
	}
	
	public static boolean isWriteableDirectory(File file)
	{
		return file.canWrite() && file.isDirectory();
	}
	
	public static boolean isExecutableDirectory(File file)
	{
		return file.canExecute() && file.isDirectory();
	}
}
